package logger

import (
	"fmt"
	"log"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"time"
)

// 日志级别
const (
	LevelDebug = iota
	LevelInfo
	LevelWarn
	LevelError
)

// 日志颜色
const (
	colorReset  = "\033[0m"
	colorRed    = "\033[31m"
	colorGreen  = "\033[32m"
	colorYellow = "\033[33m"
	colorBlue   = "\033[34m"
)

// 日志记录器
type Logger struct {
	debug   bool
	prefix  string
	logger  *log.Logger
	logFile *os.File
}

// 创建新的日志记录器
func New(debug bool) *Logger {
	// 创建日志目录
	logDir := ".deployer/logs"
	if err := os.MkdirAll(logDir, 0755); err != nil {
		log.Fatalf("创建日志目录失败: %v", err)
	}

	// 创建日志文件
	logFile, err := os.OpenFile(
		filepath.Join(logDir, fmt.Sprintf("deployer-%s.log", time.Now().Format("20060102"))),
		os.O_CREATE|os.O_APPEND|os.O_WRONLY,
		0644,
	)
	if err != nil {
		log.Fatalf("创建日志文件失败: %v", err)
	}

	return &Logger{
		debug:   debug,
		logger:  log.New(logFile, "", log.Ldate|log.Ltime|log.Lmicroseconds),
		logFile: logFile,
	}
}

// 设置前缀
func (l *Logger) WithPrefix(prefix string) *Logger {
	l.prefix = prefix
	return l
}

// 关闭日志文件
func (l *Logger) Close() error {
	if l.logFile != nil {
		return l.logFile.Close()
	}
	return nil
}

// 获取调用信息
func (l *Logger) caller() string {
	if _, file, line, ok := runtime.Caller(2); ok {
		return fmt.Sprintf("%s:%d", filepath.Base(file), line)
	}
	return "unknown"
}

// 格式化日志消息
func (l *Logger) format(level string, color string, format string, args ...interface{}) string {
	// 构建基本消息
	msg := fmt.Sprintf(format, args...)

	// 添加调用信息
	caller := l.caller()

	// 添加前缀
	prefix := ""
	if l.prefix != "" {
		prefix = fmt.Sprintf("[%s] ", l.prefix)
	}

	// 构建完整消息
	return fmt.Sprintf("%s%s[%s] %s%s%s",
		color,
		prefix,
		level,
		msg,
		colorReset,
		fmt.Sprintf(" (%s)", caller),
	)
}

// 写入日志文件
func (l *Logger) writeToFile(level, msg string) {
	// 移除颜色代码
	msg = removeColorCodes(msg)

	// 写入日志文件
	l.logger.Printf("[%s] %s", level, msg)
}

// 移除颜色代码
func removeColorCodes(s string) string {
	s = strings.ReplaceAll(s, colorReset, "")
	s = strings.ReplaceAll(s, colorRed, "")
	s = strings.ReplaceAll(s, colorGreen, "")
	s = strings.ReplaceAll(s, colorYellow, "")
	s = strings.ReplaceAll(s, colorBlue, "")
	return s
}

// Debug级别日志
func (l *Logger) Debug(format string, args ...interface{}) {
	if l.debug {
		msg := l.format("DEBUG", colorBlue, format, args...)
		fmt.Println(msg)
		l.writeToFile("DEBUG", msg)
	}
}

// Info级别日志
func (l *Logger) Info(format string, args ...interface{}) {
	msg := l.format("INFO", colorGreen, format, args...)
	fmt.Println(msg)
	l.writeToFile("INFO", msg)
}

// Warn级别日志
func (l *Logger) Warn(format string, args ...interface{}) {
	msg := l.format("WARN", colorYellow, format, args...)
	fmt.Println(msg)
	l.writeToFile("WARN", msg)
}

// Error级别日志
func (l *Logger) Error(format string, args ...interface{}) {
	msg := l.format("ERROR", colorRed, format, args...)
	fmt.Println(msg)
	l.writeToFile("ERROR", msg)
}

// Fatal级别日志
func (l *Logger) Fatal(format string, args ...interface{}) {
	msg := l.format("FATAL", colorRed, format, args...)
	fmt.Println(msg)
	l.writeToFile("FATAL", msg)
	os.Exit(1)
}
